package com.frank.oj.manager;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.text.UnicodeUtil;
import com.frank.oj.config.NacosSwitchConfig;
import com.frank.oj.config.WebConfig;
import com.frank.oj.constant.Constants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.Date;
import java.util.Properties;

/**
 * @author frank
 * @Date 2024/3/27
 */
@Component
@Slf4j
@RefreshScope
public class EmailManager {
    @Resource
    private NacosSwitchConfig nacosSwitchConfig;
    @Resource
    private TemplateEngine templateEngine;

    // 邮箱配置
  /*  @Value("${email-username}")
    private String emailUsername;

    @Value("${email-password}")
    private String emailPassword;*/
    public boolean isOk() {
        WebConfig webConfig = nacosSwitchConfig.getWebConfig();
        return webConfig.getEmailUsername() != null &&
                webConfig.getEmailPassword() != null &&
                !webConfig.getEmailUsername().equals("your_email_username") &&
                !webConfig.getEmailPassword().equals("your_email_password") &&
                Validator.isEmail(webConfig.getEmailUsername());
    }

    /**
     * 发送注册验证码邮件到指定邮箱。
     *
     * @param email 需要发送验证码的邮箱地址。
     * @param code  生成的注册验证码。
     */
    @Async
    public void sendRegisterCode(String email, String code) {
        email=email.trim();
        // 设置验证码过期时间，为当前时间后5分钟
        DateTime expireTime = DateUtil.offsetMinute(new Date(), 5);

        JavaMailSenderImpl mailSender = getMailSender();
        MimeMessage mimeMessage = mailSender.createMimeMessage();

        try {
            // 创建邮件辅助对象，用于设置邮件内容
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);

            // 上下文设置，用于动态生成邮件内容
            Context context = new Context();
            WebConfig webConfig = nacosSwitchConfig.getWebConfig();
            context.setVariable(Constants.Email.OJ_NAME.name(), UnicodeUtil.toString(webConfig.getName()));
            context.setVariable(Constants.Email.OJ_SHORT_NAME.name(), UnicodeUtil.toString(webConfig.getShortName()));
            context.setVariable(Constants.Email.OJ_URL.name(), webConfig.getBaseUrl());
            context.setVariable(Constants.Email.EMAIL_BACKGROUND_IMG.name(), webConfig.getEmailBGImg());
            context.setVariable("CODE", code);
            context.setVariable("EXPIRE_TIME", expireTime.toString());

            // 使用模板引擎处理邮件内容
            String emailContent = templateEngine.process("emailTemplate_registerCode", context);

            // 设置邮件主题和内容，以及收件人、发件人信息
            mimeMessageHelper.setSubject(UnicodeUtil.toString(webConfig.getShortName()) + "的注册验证邮件");
            mimeMessageHelper.setText(emailContent, true);
            mimeMessageHelper.setTo(email);
            mimeMessageHelper.setFrom(webConfig.getEmailUsername());

            // 发送邮件
            mailSender.send(mimeMessage);

        } catch (MessagingException e) {
            // 记录邮件发送异常
            log.error("*******HC:" + e.getMessage());
        }
    }

    /**
     * 通用邮件发送
     * @param email 邮件发送地址
     * @param subject 标题
     * @param content 内容
     */
    @Async
    public void sengCommonEmail(String email,String subject, String content) {
        WebConfig webConfig = nacosSwitchConfig.getWebConfig();
        JavaMailSenderImpl mailSender = getMailSender();

        MimeMessage mimeMessage = mailSender.createMimeMessage();
        try {
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage,
                    true);
            // 设置渲染到html页面对应的值
            Context context = new Context();

            context.setVariable(Constants.Email.OJ_NAME.name(), UnicodeUtil.toString(webConfig.getName()));
            context.setVariable(Constants.Email.OJ_SHORT_NAME.name(), UnicodeUtil.toString(webConfig.getShortName()));
            context.setVariable(Constants.Email.OJ_URL.name(), webConfig.getBaseUrl());
            context.setVariable(Constants.Email.EMAIL_BACKGROUND_IMG.name(), webConfig.getEmailBGImg());
            context.setVariable("CONTENT",content);
            //利用模板引擎加载html文件进行渲染并生成对应的字符串
            String emailContent = templateEngine.process("emailTemplate_common", context);

            mimeMessageHelper.setSubject(subject);

            mimeMessageHelper.setText(emailContent, true);
            // 收件人
            mimeMessageHelper.setTo(email);
            // 发送人
            mimeMessageHelper.setFrom(webConfig.getEmailUsername());
            mailSender.send(mimeMessage);
        } catch (MessagingException e) {
            log.error("通用邮件发送发生异常------------>{}", e.getMessage());
        }
    }
    /**
     * 重置密码
     *
     * @param username 用户名
     * @param email    用户邮箱
     * @param code     随机生成20位数字与字母的组合
     */
    @Async
    public void sendResetPassword(String username, String code, String email) {
        DateTime expireTime = DateUtil.offsetMinute(new Date(), 5);
        JavaMailSenderImpl mailSender = getMailSender();
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        try {
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage,
                    true);
            // 设置渲染到html页面对应的值
            Context context = new Context();
            WebConfig webConfig = nacosSwitchConfig.getWebConfig();
            context.setVariable(Constants.Email.OJ_NAME.name(), UnicodeUtil.toString(webConfig.getName()));
            context.setVariable(Constants.Email.OJ_SHORT_NAME.name(), UnicodeUtil.toString(webConfig.getShortName()));
            context.setVariable(Constants.Email.OJ_URL.name(), webConfig.getBaseUrl());
            context.setVariable(Constants.Email.EMAIL_BACKGROUND_IMG.name(), webConfig.getEmailBGImg());

            String resetUrl;
            if (webConfig.getBaseUrl().endsWith("/")) {
                resetUrl = webConfig.getBaseUrl() + "reset-password?username=" + username + "&code=" + code;
            } else {
                resetUrl = webConfig.getBaseUrl() + "/reset-password?username=" + username + "&code=" + code;
            }

            context.setVariable("RESET_URL", resetUrl);
            context.setVariable("EXPIRE_TIME", expireTime.toString());
            context.setVariable("USERNAME", username);

            //利用模板引擎加载html文件进行渲染并生成对应的字符串
            String emailContent = templateEngine.process("emailTemplate_resetPassword", context);

            mimeMessageHelper.setSubject(UnicodeUtil.toString(webConfig.getShortName()) + "的重置密码邮件");

            mimeMessageHelper.setText(emailContent, true);
            // 收件人
            mimeMessageHelper.setTo(email);
            // 发送人
            mimeMessageHelper.setFrom(webConfig.getEmailUsername());
            mailSender.send(mimeMessage);
        } catch (MessagingException e) {
            log.error("用户重置密码的邮件任务发生异常------------>{}", e.getMessage());
        }
    }

    /**
     * 超级管理员后台修改邮件系统配置后发送的测试邮箱可用性的测试邮件
     *
     * @param email 用户邮箱
     */
    @Async
    public void testEmail(String email) {
        JavaMailSenderImpl mailSender = getMailSender();
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        try {
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage,
                    true);
            // 设置渲染到html页面对应的值
            Context context = new Context();
            WebConfig webConfig = nacosSwitchConfig.getWebConfig();
            context.setVariable(Constants.Email.OJ_NAME.name(), UnicodeUtil.toString(webConfig.getName()));
            context.setVariable(Constants.Email.OJ_SHORT_NAME.name(), UnicodeUtil.toString(webConfig.getShortName()));
            context.setVariable(Constants.Email.OJ_URL.name(), webConfig.getBaseUrl());
            context.setVariable(Constants.Email.EMAIL_BACKGROUND_IMG.name(), webConfig.getEmailBGImg());
            //利用模板引擎加载html文件进行渲染并生成对应的字符串
            String emailContent = templateEngine.process("emailTemplate_testEmail", context);

            mimeMessageHelper.setSubject(UnicodeUtil.toString(webConfig.getShortName()) + "的测试邮件");

            mimeMessageHelper.setText(emailContent, true);
            // 收件人
            mimeMessageHelper.setTo(email);
            // 发送人
            mimeMessageHelper.setFrom(webConfig.getEmailUsername());
            mailSender.send(mimeMessage);
        } catch (MessagingException e) {
            log.error("超级管理员重置邮件系统配置的测试邮箱可用性的任务发生异常------------>{}", e.getMessage());
        }
    }

    /**
     * 为正在修改邮箱的用户的新邮箱发送验证码
     *
     * @param email 用户邮箱
     * @param code  生成的六位随机数字验证码
     */
    public void sendChangeEmailCode(String email, String username, String code) {
        DateTime expireTime = DateUtil.offsetMinute(new Date(), 10);
        JavaMailSenderImpl mailSender = getMailSender();
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        try {
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
            // 设置渲染到html页面对应的值
            Context context = new Context();
            WebConfig webConfig = nacosSwitchConfig.getWebConfig();
            context.setVariable(Constants.Email.OJ_NAME.name(), UnicodeUtil.toString(webConfig.getName()));
            context.setVariable(Constants.Email.OJ_SHORT_NAME.name(), UnicodeUtil.toString(webConfig.getShortName()));
            context.setVariable(Constants.Email.OJ_URL.name(), webConfig.getBaseUrl());
            context.setVariable(Constants.Email.EMAIL_BACKGROUND_IMG.name(), webConfig.getEmailBGImg());
            context.setVariable("CODE", code);
            context.setVariable("USERNAME", username);
            context.setVariable("EXPIRE_TIME", expireTime.toString());

            //利用模板引擎加载html文件进行渲染并生成对应的字符串
            String emailContent = templateEngine.process("emailTemplate_changeEmailCode", context);

            // 设置邮件标题
            mimeMessageHelper.setSubject(UnicodeUtil.toString(webConfig.getShortName()) + "的修改邮箱邮件");
            mimeMessageHelper.setText(emailContent, true);
            // 收件人
            mimeMessageHelper.setTo(email);
            // 发送人
            mimeMessageHelper.setFrom(webConfig.getEmailUsername());

            mailSender.send(mimeMessage);
        } catch (MessagingException e) {
            log.error("用户修改邮箱的邮件任务发生异常------------>{}", e.getMessage());
        }
    }

    /**
     * 获取邮件发送器实例。
     *
     * @return 配置好的JavaMailSenderImpl实例，可用于发送电子邮件。
     */
    private JavaMailSenderImpl getMailSender() {
        // 从nacos配置中获取web配置
        WebConfig webConfig = nacosSwitchConfig.getWebConfig();
        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();

        // 设置邮件发送的基本信息
        mailSender.setHost(webConfig.getEmailHost());
        mailSender.setPort(webConfig.getEmailPort());
        mailSender.setDefaultEncoding("UTF-8");
        mailSender.setUsername(webConfig.getEmailUsername());
        mailSender.setPassword(webConfig.getEmailPassword());

        // 配置SMTP相关的属性，包括SSL启用、认证和STARTTLS启用
        Properties properties = new Properties();
        properties.setProperty("mail.smtp.ssl.enable", webConfig.getEmailSsl().toString());
        properties.setProperty("mail.smtp.auth", "true");
        properties.setProperty("mail.smtp.starttls.enable", webConfig.getEmailSsl().toString());

        // 将SMTP属性设置到邮件发送器中
        mailSender.setJavaMailProperties(properties);
        return mailSender;
    }


}
